package com.tapstitch.scm.common.utils.http;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * https client utils
 *
 * @author luxiao
 *
 */
public class HttpClientHelper {

	private static String ENCODE = "UTF-8";

	private static Logger logger = LoggerFactory.getLogger(HttpClientHelper.class);

	// 从连接池获取连接的timeout
	private static final int connectionRequestTimeout = 3000;
	// 客户端和服务器建立连接的timeout
	private static final int connetionTimeout = 60000;
	// 客户端从服务器读取数据的timeout
	private static final int socketTimeout = 60000;

	// 用于创建普通的http连接
	private static HttpClientBuilder httpClientBuilder = null;
	static {
		httpClientBuilder = HttpClientBuilder.create();
		RequestConfig.Builder custom = RequestConfig.custom();
		custom.setConnectionRequestTimeout(connectionRequestTimeout).setConnectTimeout(connetionTimeout)
				.setSocketTimeout(socketTimeout);
		httpClientBuilder.setDefaultRequestConfig(custom.build());
	}

	// 用于创建https连接
	private static HttpClientBuilder httpsClientBuilder = null;
	static {
		try {
			SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
			sslContextBuilder.loadTrustMaterial(new TrustStrategy() {

				@Override
				public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return true;
				}
			});
			SSLContext sslContext = sslContextBuilder.build();
			SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,
					new NoopHostnameVerifier());

			httpsClientBuilder = HttpClients.custom().setSSLSocketFactory(sslSocketFactory);
		} catch (Exception e) {
			logger.warn("[http-utils]创建https通道的httpClientBuilder失败，请检查:{}", e.getMessage());
			httpsClientBuilder = HttpClientBuilder.create();
		}

		RequestConfig.Builder custom = RequestConfig.custom();
		custom.setConnectionRequestTimeout(connectionRequestTimeout).setConnectTimeout(connetionTimeout)
				.setSocketTimeout(socketTimeout);
		httpsClientBuilder.setDefaultRequestConfig(custom.build());
	}

	/**
	 * 上传文件
	 * @param url
	 * @param fileContent
	 * @return
	 */
	public static String uploadFile(String url, String fileContent, String fileName) {
		if (url == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader("User-Agent", "Java/1.7.0_79");

			MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
			multipartEntityBuilder.addBinaryBody("file",fileContent.getBytes("UTF-8"),ContentType.create("text/plain",Charset.forName("UTF-8")),fileName);
			org.apache.http.HttpEntity httpEntity = multipartEntityBuilder.build();
			httpPost.setEntity(httpEntity);

			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}, response:{}", url, JSON.toJSONString(response));
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 发起一个get请求；
	 *
	 * @param url
	 * @return
	 *
	 *         <pre>
	 * 当结果返回null时，有以下可能：
	 * 	1. 参数为空
	 * 	2. 返回的http状态码不是200
	 *  3. 发生异常
	 *  调用端需要根据自身的业务规则去判断，当得到null时，要怎么继续接下来的业务逻辑
	 *         </pre>
	 *
	 *         <strong>注：一定要慎重考虑结果为null时的处理逻辑</strong>
	 */
	public static String read(String url) {
		return read(url, null);
	}
	public static String read(String url, Map<String, String> headers) {
		if (url == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpGet httpGet = new HttpGet(url);
			httpGet.setHeader("User-Agent", "Java/1.7.0_79");
			if(headers !=null){
				Iterator<Entry<String, String>> iterator = headers.entrySet().iterator();
				while(iterator.hasNext()){
					Entry<String, String> next = iterator.next();
					httpGet.setHeader(next.getKey(), next.getValue());
				}
			}
			HttpResponse response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}, response:{}", url, JSON.toJSONString(response));
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage(), e);
		}
		return null;
	}

	public static byte[] readAndGetBytes(String url, Map<String, String> headers) {
		if (url == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpGet httpGet = new HttpGet(url);
			httpGet.setHeader("User-Agent", "Java/1.7.0_79");
			if(headers !=null){
				Iterator<Entry<String, String>> iterator = headers.entrySet().iterator();
				while(iterator.hasNext()){
					Entry<String, String> next = iterator.next();
					httpGet.setHeader(next.getKey(), next.getValue());
				}
			}
			HttpResponse response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}, response:{}", url, JSON.toJSONString(response));
				return null;
			}
			byte[] responseData = EntityUtils.toByteArray(response.getEntity());
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage(), e);
		}
		return null;
	}
	/**
	 * 发起一个post请求；
	 *
	 * @param url
	 * @param data
	 * @return
	 *
	 *         <pre>
	 * 当结果返回null时，有以下可能：
	 * 	1. 参数为空
	 * 	2. 返回的http状态码不是200 || 202
	 *  3. 发生异常
	 *  调用端需要根据自身的业务规则去判断，当得到null时，要怎么继续接下来的业务逻辑
	 *         </pre>
	 *
	 *         <strong>注：一定要慎重考虑结果为null时的处理逻辑</strong>
	 */
	public static String write(String url, String data) {
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		return write(url, data, selectClientBuilder, null);
	}

	/**
	 * 发起一个post请求；
	 * 设置头请求类型的
	 * @param url
	 * @param data
	 * @param headerMap
     * @return
     */
	public static String write(String url, String data, Map<String, String> headerMap) {
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		return write(url, data, selectClientBuilder, headerMap);
	}

	public static String write(String url, String data, HttpClientBuilder selectClientBuilder, Map<String, String> headerMap) {
		if (url == null || data == null) {
			return null;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			StringEntity stringEntity = new StringEntity(data, ENCODE);
			httpPost.setEntity(stringEntity);
			if(headerMap != null) {
				for (Entry<String, String> e : headerMap.entrySet()) {
					httpPost.setHeader(e.getKey(), e.getValue());
				}
			}
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				String errData = "";
				try{
					errData = EntityUtils.toString(response.getEntity(), ENCODE);
				} catch (Exception e) {
					// 忽略异常，可能无法读取内容
				}
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{},data:{}", url, errData);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}


	public static byte[] writeAndGetBytes(String url, String data) {
		if (url == null || data == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			StringEntity stringEntity = new StringEntity(data, ENCODE);
			httpPost.setEntity(stringEntity);
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}", url);
				return null;
			}
			byte[] responseData = EntityUtils.toByteArray(response.getEntity());
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static byte[] writeAndGetBytes(String url, String data, Map<String, String> headerMap) {
		if (url == null || data == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}

		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			StringEntity stringEntity = new StringEntity(data, ENCODE);
			httpPost.setEntity(stringEntity);
			if (!CollectionUtils.isEmpty(headerMap)) {
				headerMap.forEach(httpPost::setHeader);
			}
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}", url);
				return null;
			}
			byte[] responseData = EntityUtils.toByteArray(response.getEntity());
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}


	public static String put(String url, String data, Map<String, String> headerMap) {
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		return put(url, data, selectClientBuilder, headerMap);
	}

	public static String delete(String url, Map<String, String> headerMap) {
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		return delete(url, selectClientBuilder, headerMap);
	}



	public static String put(String url, String data, HttpClientBuilder selectClientBuilder, Map<String, String> headerMap) {
		if (url == null || data == null) {
			return null;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPut httpPost = new HttpPut(url);
			StringEntity stringEntity = new StringEntity(data, ENCODE);
			httpPost.setEntity(stringEntity);
			if (!CollectionUtils.isEmpty(headerMap)) {
				headerMap.forEach(httpPost::setHeader);
			}
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				String errData = "";
				try{
					String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
					errData = responseData;
				} catch (Exception e) {
					// 忽略异常，可能无法读取内容
				}
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{},data:{}", url, errData);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static String delete(String url, HttpClientBuilder selectClientBuilder, Map<String, String> headerMap) {
		if (url == null) {
			return null;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpDelete httpPost = new HttpDelete(url);
			if (!CollectionUtils.isEmpty(headerMap)) {
				headerMap.forEach(httpPost::setHeader);
			}
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				String errData = "";
				try{
					String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
					errData = responseData;
				} catch (Exception e) {
					// 忽略异常，可能无法读取内容
				}
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{},data:{}", url, errData);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static String write(String url, Map<String, String> data) {
		if (url == null || data == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
//			httpPost.setHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
			List<NameValuePair> nameValuePairs = new ArrayList<>();
			Iterator<Entry<String, String>> iterator = data.entrySet().iterator();
			while (iterator.hasNext()) {
				Entry<String, String> entry = iterator.next();
				nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, ENCODE));

			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200,是:{}，url:{}", response.getStatusLine().getStatusCode(), url);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static String write(String url, Map<String, String> data, Map<String, String> headerMap) {
		if (url == null || data == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			if (!CollectionUtils.isEmpty(headerMap)) {
				headerMap.forEach(httpPost::setHeader);
			}
			List<NameValuePair> nameValuePairs = new ArrayList<>();
			Iterator<Entry<String, String>> iterator = data.entrySet().iterator();
			while (iterator.hasNext()) {
				Entry<String, String> entry = iterator.next();
				nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, ENCODE));

			HttpResponse response = httpClient.execute(httpPost);
			org.springframework.http.HttpStatus httpStatus = org.springframework.http.HttpStatus.resolve(response.getStatusLine().getStatusCode());
			if (httpStatus == null || !httpStatus.is2xxSuccessful()) {
				logger.warn("[http-utils]执行http请求时，返回结果不是2xx,是:{}，url:{}", response.getStatusLine().getStatusCode(), url);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static String write(String url, List<Pair<String, String>> data, Map<String, String> headerMap) {
		if (url == null || data == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			if (!CollectionUtils.isEmpty(headerMap)) {
				headerMap.forEach(httpPost::setHeader);
			}
			List<NameValuePair> nameValuePairs = data.stream().map(o -> new BasicNameValuePair(o.getKey(), o.getValue())).collect(Collectors.toList());
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, ENCODE));

			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200,是:{}，url:{}", response.getStatusLine().getStatusCode(), url);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	/**
	 * Post 请求使用 json 格式数据
	 * @param url
	 * @param data 该方法会自动将 map 中的数据转化为 json 格式
	 * @param headerMap
	 * @return
	 */
	public static String writeJson(String url, Map<String, String> data, Map<String, String> headerMap) {
		if (url == null || data == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build()) {
			HttpPost httpPost = new HttpPost(url);
			if (!CollectionUtils.isEmpty(headerMap)) {
				headerMap.forEach(httpPost::setHeader);
			}
			String jsonData = JSON.toJSONString(data);
			StringEntity requestEntity = new StringEntity(jsonData, ContentType.APPLICATION_JSON);
			httpPost.setEntity(requestEntity);

			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200,是:{}，url:{}", response.getStatusLine().getStatusCode(), url);
				return null;
			}
			String responseData = EntityUtils.toString(response.getEntity(), ENCODE);
			if (logger.isDebugEnabled()) {
				logger.debug("[http-utils]执行http请求时，返回， url: {}, data:{}", url, responseData);
			}
			return responseData;
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	/**
	 * 下载文件
	 *
	 * @param url
	 * @return
	 */
	public static byte[] downloadPostImage(String url, String data, boolean checkContentType) {
		if (url == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build();) {
			HttpPost httpPost = new HttpPost(url);
			httpPost.setEntity(new StringEntity(data, ENCODE));
			HttpResponse response = httpClient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}", url);
				return null;
			}
			boolean headerCheckPass = true;
			if (checkContentType) {
				Header[] headers = response.getHeaders("Content-Type");
				if (headers != null) {
					for (Header header : headers) {
						String val = header.getValue();
						if (val.contains("json")) {
							headerCheckPass = false;
							break;
						}
					}
				}
			}
			if (!headerCheckPass) {
				String responseStr = EntityUtils.toString(response.getEntity());
				logger.warn("[http-utils]执行http下载请求时，返回响应头错误，url:{},response:{}", url, responseStr);
				return null;
			}
			return EntityUtils.toByteArray(response.getEntity());
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static byte[] download(String url) {
		if (url == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		try (CloseableHttpClient httpClient = selectClientBuilder.build();) {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}", url);
				return null;
			}
			return EntityUtils.toByteArray(response.getEntity());
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}

	public static InputStream downloadIs(String url) {
		if (url == null) {
			return null;
		}
		HttpClientBuilder selectClientBuilder = null;
		if (url.startsWith("https://")) {
			selectClientBuilder = httpsClientBuilder;
		} else {
			selectClientBuilder = httpClientBuilder;
		}
		CloseableHttpClient httpClient = selectClientBuilder.build();
		try  {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				logger.warn("[http-utils]执行http请求时，返回结果不是200，url:{}", url);
				return null;
			}
			return response.getEntity().getContent();
		} catch (IOException e) {
			logger.warn("[http-utils]执行http请求时发生异常，url:{}, error:{}", url, e.getMessage());
		}
		return null;
	}


	/**
	 * 向指定 URL 发送POST方法的请求
	 *
	 * @param url
	 *            发送请求的 URL
	 * @param param
	 *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
	 * @return 所代表远程资源的响应结果
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			logger.warn("发送 POST 请求出现异常，url：{}?{}", url, param);
			System.out.println("发送 POST 请求出现异常！"+e);
			e.printStackTrace();
		}
		//使用finally块来关闭输出流、输入流
		finally{
			try{
				if(out!=null){
					out.close();
				}
				if(in!=null){
					in.close();
				}
			}
			catch(IOException ex){
				ex.printStackTrace();
			}
		}
		return result;
	}
}
